/*
    Implementation of spin lock
 */

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

public class SpinLock {
    AtomicReference<Thread> atomicReference = new AtomicReference<>();
    public void lock(){
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName()+"\t try to lock");
        while (!atomicReference.compareAndSet(null, thread));
        System.out.println(thread.getName()+"\t lock success");
    }

    public void un_lock(){
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName()+"\t unlock success");
        atomicReference.compareAndSet(thread, null);
    }
    public static void main(String[] args) {
        SpinLock spinLock = new SpinLock();

        new Thread(()->{
            spinLock.lock();
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                spinLock.un_lock();
            }
        },"t1").start();

        new Thread(()->{
            spinLock.lock();
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                spinLock.un_lock();
            }
        },"t2").start();
    }
}
